// PairCalculatorMain.cpp : implementation file
//

#include "stdafx.h"
#include "LightspeedTraderAPIDemo.h"
#include "PairCalculatorMain.h"
#include "afxdialogex.h"
#include "PairTrade.h"
#include "PairCalculatorDetail.h"
#include <algorithm>
#include <fstream>

using namespace std;


// PairCalculatorMain dialog

IMPLEMENT_DYNAMIC(PairCalculatorMain, CModelessDialog)

PairCalculatorMain::PairCalculatorMain(CWnd* pParent /*=NULL*/)
	: CModelessDialog(PairCalculatorMain::IDD, pParent),
	isFormClosing(false)
	,account(0)
	,bHeaderClickedStart(true)
{
	
}

PairCalculatorMain::~PairCalculatorMain()
{
	for(size_t rowId = 0; rowId < m_DataModel.m_Records.size() ; ++rowId)
	{
		DeleteSummary(m_DataModel.m_Records[rowId].BuyTrade);
		DeleteSummary(m_DataModel.m_Records[rowId].SellTrade);
	}
	L_DetachFromAppNotifier(this);
	if (account)
	{
		account->L_Detach(this);
	}

}

BOOL PairCalculatorMain::Create(CWnd *pParentWnd /*= CWnd::FromHandle(L_GetMainWnd())*/)
{
	return __super::Create(PairCalculatorMain::IDD, pParentWnd);
}

void PairCalculatorMain::DoDataExchange(CDataExchange* pDX)
{
	//CDialog::DoDataExchange(pDX);
	__super::DoDataExchange(pDX);

	DDX_Control(pDX, IDC_PAIR_LIST, m_PairDataListCtrl);
}

BOOL PairCalculatorMain::OnInitDialog()
{
	__super::OnInitDialog();

	account = L_GetAccount();
	account->L_Attach(this);

	DWORD style = m_PairDataListCtrl.GetExtendedStyle();
	style |= LVS_EX_FULLROWSELECT;
	style |= LVS_EX_GRIDLINES;
	style |= LVS_EX_DOUBLEBUFFER;
	m_PairDataListCtrl.SetExtendedStyle(style);

	InitializeDataCtrlRows();
	
	ifstream MyFile;
	MyFile.open ("C:\\PT\\Users.csv") ;
	CString ptStr;
	string value;
	while ( MyFile.good() )
	{
		getline ( MyFile, value ); // read a string until next comma: http://www.cplusplus.com/reference/string/getline/
		char *cstr = new char[value.length() + 1];
		strcpy(cstr, value.c_str());
		char* Token = strtok(cstr, ",");
		CString strx[17];
		int i =0;
		while(Token != NULL)
		{
			strx[i++] = Token;
			// Tokenize the remaning string.
			Token = strtok(0, ",");
		};

		DumpClass newPair;
		int nItem = 0;
		newPair.Comparison					= strx[0];
		newPair.RequiredSpred				= atof(strx[1]);
		newPair.RealizedSpread				= atof(strx[2]);
		newPair.Nature						= strx[3][0];
		newPair.Ratio						= atof(strx[4]);

		newPair.BuyTradeQty					= atoi(strx[5]);
		newPair.BuyTradeCash				= atof(strx[6]);
		newPair.BuyTradePriceOn				= strx[7];
		newPair.BuyTradeOrderPriceOn		= strx[8];
		newPair.BuyTradeOrderDestination	= strx[9];
		newPair.BuyTradeStockName			= strx[10];

		newPair.SellTradeQty				= atoi(strx[11]);
		newPair.SellTradeCash				= atof(strx[12]);
		newPair.SellTradePriceOn			= strx[13];
		newPair.SellTradeOrderPriceOn		= strx[14];
		newPair.SellTradeOrderDestination	= strx[15];
		newPair.SellTradeStockName			= strx[16];

		if(newPair.BuyTradeQty == 0 || newPair.SellTradeQty == 0)
		{
			continue;
		}
		
		delete [] cstr;
		delete [] Token;
		//delete [] strx;

		PairTrade pt;
		pt.Comparison					= newPair.Comparison;		
		pt.RequiredSpred				= newPair.RequiredSpred;	
		pt.Evalution					= newPair.Evalution;	
		pt.RealizedSpread				= newPair.RealizedSpread;		
		pt.PairSize						= newPair.PairSize;	
		pt.Nature						= newPair.Nature;		
		pt.Ratio						= newPair.Ratio;	
		pt.IsActive						= false;													
		pt.IsExecuted					= false;	
		pt.BuyTrade->Qty				= newPair.BuyTradeQty;		
		pt.BuyTrade->Price				= newPair.BuyTradePrice;		
		pt.BuyTrade->Cash				= newPair.BuyTradeCash;		
		pt.BuyTrade->PriceOn			= newPair.BuyTradePriceOn;		
		pt.BuyTrade->OrderPriceOn		= newPair.BuyTradeOrderPriceOn;		
		pt.BuyTrade->OrderDestination	= newPair.BuyTradeOrderDestination;
																		
		pt.BuyTrade->Stock.Name			= newPair.BuyTradeStockName;
		pt.BuyTrade->Stock.Open			= newPair.BuyTradeStockOpen;
		pt.BuyTrade->Stock.Low			= newPair.BuyTradeStockLow;	
		pt.BuyTrade->Stock.High			= newPair.BuyTradeStockHigh;
		pt.BuyTrade->Stock.Close		= newPair.BuyTradeStockClose;	
		pt.BuyTrade->Stock.Bid			= newPair.BuyTradeStockBid;	
		pt.BuyTrade->Stock.Ask			= newPair.BuyTradeStockAsk;	
		pt.BuyTrade->Stock.Ratio		= newPair.BuyTradeStockRatio;	
																		
		pt.SellTrade->Qty				= newPair.SellTradeQty;	
		pt.SellTrade->Price				= newPair.SellTradePrice;	
		pt.SellTrade->Cash				= newPair.SellTradeCash;	
		pt.SellTrade->PriceOn			= newPair.SellTradePriceOn;	
		pt.SellTrade->OrderPriceOn		= newPair.SellTradeOrderPriceOn;	
		pt.SellTrade->OrderDestination	= newPair.SellTradeOrderDestination;	
																		
		pt.SellTrade->Stock.Name		= newPair.SellTradeStockName;
		pt.SellTrade->Stock.Open		= newPair.SellTradeStockOpen;
		pt.SellTrade->Stock.Low			= newPair.SellTradeStockLow;
		pt.SellTrade->Stock.High		= newPair.SellTradeStockHigh;	
		pt.SellTrade->Stock.Close		= newPair.SellTradeStockClose;	
		pt.SellTrade->Stock.Bid			= newPair.SellTradeStockBid;
		pt.SellTrade->Stock.Ask			= newPair.SellTradeStockAsk;
		pt.SellTrade->Stock.Ratio		= newPair.SellTradeStockRatio;	
		
		CreateSummary(pt.BuyTrade);
		CreateSummary(pt.SellTrade);
		m_DataModel.m_Records.push_back(pt);
	}
	MyFile.close();

	FillGrid();
	
	L_AttachToAppNotifier(this);

	return TRUE;
}
//L_Oberver
void PairCalculatorMain::HandleMessage(L_Message const *pMsg)
{
	long returnType = pMsg->L_Type();
	switch(returnType)
	{
	case L_MsgSymbolChanged::id:
		{
			//if (m_Linked)
			if(m_DataModel.m_Records.size() > 0)
			{
				//SetSymbol(pMsg->L_Symbol());
			}
		}
		break;
	case L_MsgL1::id:
	case L_MsgL1Change::id:
	case L_MsgIndex::id:
		{
			//UpdateStaticValues();
			//UpdateL1Values();
		}
		break;
	case L_MsgL1Update::id:
	case L_MsgIndexUpdate::id:
		{
			//UpdateL1Values();
			GetLivePrice();
		}
		break;
	case L_MsgChartSnapshot::id:
	case L_MsgChartUpdate::id:
		{
			//UpdateTFValues();
		}
		break;
	case L_MsgOrderImbalance::id:
		{
			//UpdateOIValues();
		}
		break;
	case L_MsgError::id:
		{
			//ClearValues();
		}
		break;
	}
}

BEGIN_MESSAGE_MAP(PairCalculatorMain, CDialog)
	ON_WM_SIZE()
	ON_BN_CLICKED(ID_PAIR_NEW, &PairCalculatorMain::OnBnClickedPairNew)
	ON_BN_CLICKED(ID_PAIR_OPEN, &PairCalculatorMain::OnBnClickedPairOpen)
	ON_BN_CLICKED(ID_PAIR_DELETE, &PairCalculatorMain::OnBnClickedPairDelete)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDOK, &PairCalculatorMain::OnBnClickedOk)
	ON_WM_CLOSE()
	ON_BN_CLICKED(ID_PAIR_COPPY, &PairCalculatorMain::OnBnClickedPairCoppy)
	ON_BN_CLICKED(ID_PAIR_SELECTALL, &PairCalculatorMain::OnBnClickedPairSelectall)
	ON_BN_CLICKED(ID_PAIR_DESELECTALL, &PairCalculatorMain::OnBnClickedPairDeselectall)
	ON_BN_CLICKED(ID_PAIR_ACTIVATE, &PairCalculatorMain::OnBnClickedPairActivate)
	ON_BN_CLICKED(ID_PAIR_DEACTIVATE, &PairCalculatorMain::OnBnClickedPairDeactivate)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_PAIR_LIST, OnCustomdrawList)
	ON_NOTIFY(HDN_ITEMCLICK, 0, &PairCalculatorMain::OnHeaderClick)
END_MESSAGE_MAP()


void PairCalculatorMain::GetLivePrice()
{
	if(!isFormClosing)
	{
		if(m_DataModel.m_Records.size() > 0)
		{
			for(size_t rowId = 0; rowId < m_DataModel.m_Records.size() ; ++rowId)
			{
				PairTrade *pairTrade = new PairTrade();
				pairTrade = &m_DataModel.m_Records[rowId];

				if(pairTrade->BuyTrade->PriceOn == "B")
				{
					pairTrade->BuyTrade->Price = pairTrade->BuyTrade->Summary->L_Bid();
				}
				else if(pairTrade->BuyTrade->PriceOn == "A")
				{
					pairTrade->BuyTrade->Price = pairTrade->BuyTrade->Summary->L_Ask();
				}
				else if(pairTrade->BuyTrade->PriceOn == "L")
				{
					pairTrade->BuyTrade->Price = pairTrade->BuyTrade->Summary->L_LastPrice();
				}


				if(pairTrade->SellTrade->PriceOn == "B")
				{
					pairTrade->SellTrade->Price = pairTrade->SellTrade->Summary->L_Bid();
				}
				else if(pairTrade->SellTrade->PriceOn == "A")
				{
					pairTrade->SellTrade->Price = pairTrade->SellTrade->Summary->L_Ask();
				}
				else if(pairTrade->SellTrade->PriceOn == "L")
				{
					pairTrade->SellTrade->Price = pairTrade->SellTrade->Summary->L_LastPrice();
				}
				
				double actualSpread = 0;
				
				if(m_DataModel.m_Records[rowId].Nature == 'B')
				{
					actualSpread = pairTrade->Ratio * pairTrade->BuyTrade->Price - pairTrade->SellTrade->Price;
				}
				else
				{
					actualSpread = pairTrade->Ratio * pairTrade->SellTrade->Price - pairTrade->BuyTrade->Price;
				}
				pairTrade->ActualSpread = actualSpread;
				if(pairTrade->Comparison == ">")
				{
					if(pairTrade->ActualSpread > pairTrade->RequiredSpred)
					{
						pairTrade->Evalution = true;
					}
					else
					{
						pairTrade->Evalution = false;
					}
				}
				else if(pairTrade->Comparison == ">=")
				{
					if(pairTrade->ActualSpread >= pairTrade->RequiredSpred)
					{
						pairTrade->Evalution = true;
					}
					else
					{
						pairTrade->Evalution = false;
					}
				}
				else if(pairTrade->Comparison == "<")
				{
					if(pairTrade->ActualSpread < pairTrade->RequiredSpred)
					{
						pairTrade->Evalution = true;
					}
					else
					{
						pairTrade->Evalution = false;
					}
				}
				else if(pairTrade->Comparison == "<=")
				{
					if(pairTrade->ActualSpread <= pairTrade->RequiredSpred)
					{
						pairTrade->Evalution = true;
					}
					else
					{
						pairTrade->Evalution = false;
					}
				}
				else
				{
					pairTrade->Evalution = false;
				}
				
				//delete pairTrade;

			}
			///
			SendOrders();
		}

		FillGrid();
	}
}

void PairCalculatorMain::InitializeDataCtrlRows()
{
	CRect rect;
	m_PairDataListCtrl.GetClientRect(&rect);
	int nColInterval = rect.Width()/m_DataModel.GetColCount();

	m_PairDataListCtrl.InsertColumn(0, PairTrade().GetCellText(0, true), LVCFMT_LEFT, 170, 0);
	m_PairDataListCtrl.InsertColumn(1, PairTrade().GetCellText(1, true), LVCFMT_LEFT, 0, 0);
	m_PairDataListCtrl.InsertColumn(2, PairTrade().GetCellText(2, true), LVCFMT_LEFT, 50, 0);
	m_PairDataListCtrl.InsertColumn(3, PairTrade().GetCellText(3, true), LVCFMT_RIGHT, 50, 0);
	m_PairDataListCtrl.InsertColumn(4, PairTrade().GetCellText(4, true), LVCFMT_LEFT, 50, 0);
	m_PairDataListCtrl.InsertColumn(5, PairTrade().GetCellText(5, true), LVCFMT_RIGHT, 50, 0);
	m_PairDataListCtrl.InsertColumn(6, PairTrade().GetCellText(6, true), LVCFMT_RIGHT, 75, 0);
	m_PairDataListCtrl.InsertColumn(7, PairTrade().GetCellText(7, true), LVCFMT_LEFT, 50, 0);
	m_PairDataListCtrl.InsertColumn(8, PairTrade().GetCellText(8, true), LVCFMT_LEFT, 75, 0);
	m_PairDataListCtrl.InsertColumn(9, PairTrade().GetCellText(9, true), LVCFMT_RIGHT, 80, 0);
	m_PairDataListCtrl.InsertColumn(10, PairTrade().GetCellText(10, true), LVCFMT_RIGHT, 50, 0);
	m_PairDataListCtrl.InsertColumn(11, PairTrade().GetCellText(11, true), LVCFMT_RIGHT, 100, 0);
	m_PairDataListCtrl.InsertColumn(12, PairTrade().GetCellText(12, true), LVCFMT_LEFT, 75, 0);
}

void PairCalculatorMain::FillGrid()
{
	m_PairDataListCtrl.SetRedraw(FALSE);
	
	int nCountRecords = (int)m_DataModel.m_Records.size();
	int nCount = 1;
	while(m_PairDataListCtrl.GetItemCount() < nCountRecords)
	{
		// Insert Row
		const CString& strCellText = m_DataModel.GetCellText(nCountRecords-nCount, 0);
		m_PairDataListCtrl.InsertItem(nCountRecords-1, strCellText);
		nCount++;
	}
	for(size_t rowId = 0; rowId < m_DataModel.m_Records.size() ; ++rowId)
	{
		for(int col = 0; col < m_DataModel.GetColCount() ; ++col)
		{
			const CString& cellText = m_DataModel.GetCellText(rowId, col);
			const CString& curText = m_PairDataListCtrl.GetItemText(rowId, col);
			if(curText != cellText)
			{
				m_PairDataListCtrl.SetItemText(rowId, col, cellText);
			}
		}
	}

	m_PairDataListCtrl.SetRedraw(TRUE);
}

void PairCalculatorMain::OnBnClickedPairNew()
{
	PairTrade *newPair = NULL;
	PairCalculatorDetail *pDlg = new PairCalculatorDetail(newPair);
	INT_PTR status = pDlg->DoModal();
	switch(status)
    {
    case IDOK:
        newPair = pDlg->GetTradePair();
		if(newPair)
		{
			CreateSummary(newPair->BuyTrade);
			CreateSummary(newPair->SellTrade);
			m_DataModel.m_Records.push_back(*newPair);
		}
        break;
    case IDCANCEL:
    default:
        break;
    }
	FillGrid();

	delete newPair;
}

void PairCalculatorMain::OnBnClickedPairOpen()
{
	UINT i, uSelectedCount = m_PairDataListCtrl.GetSelectedCount();
	if(m_DataModel.m_Records.size() > 0)
	{
		PairTrade *newPair = NULL;
		int  nItem = -1;
		if (uSelectedCount > 0)
		{
		   for (i=0;i < uSelectedCount;i++)
		   {
			   nItem = m_PairDataListCtrl.GetNextItem(nItem, LVNI_SELECTED);
			   newPair = &(m_DataModel.m_Records[nItem]);
		   }
		}
		if(newPair)
		{
			PairCalculatorDetail *pDlg = new PairCalculatorDetail(newPair);
			INT_PTR status = pDlg->DoModal();
			switch(status)
			{
			case IDOK:
				{
					newPair = pDlg->GetTradePair();
					CreateSummary(newPair->BuyTrade);
					CreateSummary(newPair->SellTrade);
				}
				break;
			case IDCANCEL:
			default:
				break;
			}
			FillGrid();
			delete pDlg;
		}
		delete newPair;
	}
}

void PairCalculatorMain::OnBnClickedPairDelete()
{
	UINT i, uSelectedCount = m_PairDataListCtrl.GetSelectedCount();
	int  nItem = -1;
	if (uSelectedCount > 0)
	{
	   for (i=0;i < uSelectedCount;i++)
	   {
		  nItem = m_PairDataListCtrl.GetNextItem(nItem, LVNI_SELECTED);
		  ASSERT(nItem != -1);
		  m_DataModel.m_Records.erase(m_DataModel.m_Records.begin() + nItem);
		  m_PairDataListCtrl.DeleteItem(nItem);
	   }
	   FillGrid();
	}
}

void PairCalculatorMain::OnBnClickedOk()
{
	isFormClosing = true;
	EndDialog(1);
}

void PairCalculatorMain::OnSize(UINT nType, int cx, int cy)
{
	__super::OnSize(nType, cx, cy);
	ResizeControls();
}

void PairCalculatorMain::ResizeControls()
{
	if (m_hWnd && m_PairDataListCtrl.m_hWnd)
	{
		//get the rect of all of the controls that need to be moved/resized
		RECT clientRect;
		GetClientRect(&clientRect);

		RECT dataRect;
		m_PairDataListCtrl.GetWindowRect(&dataRect);
		ScreenToClient(&dataRect);

		dataRect.bottom = clientRect.bottom - 5;
		dataRect.right = clientRect.right - 5;

		m_PairDataListCtrl.MoveWindow(&dataRect);
	}
}

void PairCalculatorMain::OnClose()
{
	isFormClosing = true;
	try
	{
		if(m_DataModel.m_Records.size() > 0)
		{
			ofstream MyFile;
			MyFile.open ("C:\\PT\\Users.csv", ios::out | ios::ate) ;
			for(int nItem = 0; nItem < m_DataModel.m_Records.size(); nItem++)
			{
				DumpClass newPair;

				newPair.Comparison		= m_DataModel.m_Records[nItem].Comparison;
				newPair.RequiredSpred	= m_DataModel.m_Records[nItem].RequiredSpred;
				newPair.Evalution		= m_DataModel.m_Records[nItem].Evalution;
				newPair.RealizedSpread	= m_DataModel.m_Records[nItem].RealizedSpread;
				newPair.PairSize		= m_DataModel.m_Records[nItem].PairSize;
				newPair.Nature			= m_DataModel.m_Records[nItem].Nature;
				newPair.Ratio			= m_DataModel.m_Records[nItem].Ratio;
				newPair.IsActive		= false;
				newPair.IsExecuted		= false;
	
				newPair.BuyTradeQty				= m_DataModel.m_Records[nItem].BuyTrade->Qty;
				newPair.BuyTradePrice			= m_DataModel.m_Records[nItem].BuyTrade->Price;
				newPair.BuyTradeCash			= m_DataModel.m_Records[nItem].BuyTrade->Cash;
				newPair.BuyTradePriceOn			= m_DataModel.m_Records[nItem].BuyTrade->PriceOn;
				newPair.BuyTradeOrderPriceOn	= m_DataModel.m_Records[nItem].BuyTrade->OrderPriceOn;
				newPair.BuyTradeOrderDestination= m_DataModel.m_Records[nItem].BuyTrade->OrderDestination;
			
				newPair.BuyTradeStockName		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Name;
				newPair.BuyTradeStockOpen		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Open;
				newPair.BuyTradeStockLow		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Low;
				newPair.BuyTradeStockHigh		= m_DataModel.m_Records[nItem].BuyTrade->Stock.High;
				newPair.BuyTradeStockClose		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Close;
				newPair.BuyTradeStockBid		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Bid;
				newPair.BuyTradeStockAsk		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Ask;
				newPair.BuyTradeStockRatio		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Ratio;
			
				newPair.SellTradeQty			= m_DataModel.m_Records[nItem].SellTrade->Qty;
				newPair.SellTradePrice			= m_DataModel.m_Records[nItem].SellTrade->Price;
				newPair.SellTradeCash			= m_DataModel.m_Records[nItem].SellTrade->Cash;
				newPair.SellTradePriceOn		= m_DataModel.m_Records[nItem].SellTrade->PriceOn;
				newPair.SellTradeOrderPriceOn	= m_DataModel.m_Records[nItem].SellTrade->OrderPriceOn;
				newPair.SellTradeOrderDestination= m_DataModel.m_Records[nItem].SellTrade->OrderDestination;
			
				newPair.SellTradeStockName		= m_DataModel.m_Records[nItem].SellTrade->Stock.Name;
				newPair.SellTradeStockOpen		= m_DataModel.m_Records[nItem].SellTrade->Stock.Open;
				newPair.SellTradeStockLow		= m_DataModel.m_Records[nItem].SellTrade->Stock.Low;
				newPair.SellTradeStockHigh		= m_DataModel.m_Records[nItem].SellTrade->Stock.High;
				newPair.SellTradeStockClose		= m_DataModel.m_Records[nItem].SellTrade->Stock.Close;
				newPair.SellTradeStockBid		= m_DataModel.m_Records[nItem].SellTrade->Stock.Bid;
				newPair.SellTradeStockAsk		= m_DataModel.m_Records[nItem].SellTrade->Stock.Ask;
				newPair.SellTradeStockRatio		= m_DataModel.m_Records[nItem].SellTrade->Stock.Ratio;

				CString ptStr;
				ptStr.Format("%s,%.2f,%.2f,%c,%.2f,%d,%.2f,%s,%s,%s,%s,%d,%.2f,%s,%s,%s,%s\n", 
							newPair.Comparison, newPair.RequiredSpred, newPair.RealizedSpread, 
							newPair.Nature, newPair.Ratio, newPair.BuyTradeQty, newPair.BuyTradeCash, 
							newPair.BuyTradePriceOn, newPair.BuyTradeOrderPriceOn, newPair.BuyTradeOrderDestination, 
							newPair.BuyTradeStockName, newPair.SellTradeQty, newPair.SellTradeCash, newPair.SellTradePriceOn, 
							newPair.SellTradeOrderPriceOn, newPair.SellTradeOrderDestination, newPair.SellTradeStockName
					);
	
				///Writing File
				{
					MyFile << ptStr;
				}
				DeleteSummary(m_DataModel.m_Records[nItem].BuyTrade);
				DeleteSummary(m_DataModel.m_Records[nItem].SellTrade);
			}
			MyFile.close();
		}
	}
	catch(...)
	{
		//myFile.Close();	
	}

	__super::OnClose();
}

void PairCalculatorMain::OnBnClickedPairCoppy()
{
	UINT i, uSelectedCount = m_PairDataListCtrl.GetSelectedCount();
	int  nItem = -1;
	if (uSelectedCount > 0)
	{
	   for (i=0;i < uSelectedCount;i++)
	   {

			nItem = m_PairDataListCtrl.GetNextItem(nItem, LVNI_SELECTED);
			PairTrade newPair;
		   
			newPair.Comparison		= m_DataModel.m_Records[nItem].Comparison;
			newPair.RequiredSpred	= m_DataModel.m_Records[nItem].RequiredSpred;
			newPair.Evalution		= m_DataModel.m_Records[nItem].Evalution;
			newPair.RealizedSpread	= m_DataModel.m_Records[nItem].RealizedSpread;
			newPair.PairSize		= m_DataModel.m_Records[nItem].PairSize;
			newPair.Nature			= m_DataModel.m_Records[nItem].Nature;
			newPair.Ratio			= m_DataModel.m_Records[nItem].Ratio;
			newPair.IsActive		= false;
			newPair.IsExecuted		= false;

			newPair.BuyTrade					= new Trade();
			newPair.BuyTrade->Qty				= m_DataModel.m_Records[nItem].BuyTrade->Qty;
			newPair.BuyTrade->Price				= m_DataModel.m_Records[nItem].BuyTrade->Price;
			newPair.BuyTrade->Cash				= m_DataModel.m_Records[nItem].BuyTrade->Cash;
			newPair.BuyTrade->PriceOn			= m_DataModel.m_Records[nItem].BuyTrade->PriceOn;
			newPair.BuyTrade->OrderPriceOn		= m_DataModel.m_Records[nItem].BuyTrade->OrderPriceOn;
			newPair.BuyTrade->OrderDestination	= m_DataModel.m_Records[nItem].BuyTrade->OrderDestination;
			
			newPair.BuyTrade->Stock				= *(new Symbol());
			newPair.BuyTrade->Stock.Name		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Name;
			newPair.BuyTrade->Stock.Open		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Open;
			newPair.BuyTrade->Stock.Low			= m_DataModel.m_Records[nItem].BuyTrade->Stock.Low;
			newPair.BuyTrade->Stock.High		= m_DataModel.m_Records[nItem].BuyTrade->Stock.High;
			newPair.BuyTrade->Stock.Close		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Close;
			newPair.BuyTrade->Stock.Bid			= m_DataModel.m_Records[nItem].BuyTrade->Stock.Bid;
			newPair.BuyTrade->Stock.Ask			= m_DataModel.m_Records[nItem].BuyTrade->Stock.Ask;
			newPair.BuyTrade->Stock.Ratio		= m_DataModel.m_Records[nItem].BuyTrade->Stock.Ratio;
			
			newPair.SellTrade					= new Trade();
			newPair.SellTrade->Qty				= m_DataModel.m_Records[nItem].SellTrade->Qty;
			newPair.SellTrade->Price			= m_DataModel.m_Records[nItem].SellTrade->Price;
			newPair.SellTrade->Cash				= m_DataModel.m_Records[nItem].SellTrade->Cash;
			newPair.SellTrade->PriceOn			= m_DataModel.m_Records[nItem].SellTrade->PriceOn;
			newPair.SellTrade->OrderPriceOn		= m_DataModel.m_Records[nItem].SellTrade->OrderPriceOn;
			newPair.SellTrade->OrderDestination	= m_DataModel.m_Records[nItem].SellTrade->OrderDestination;
			
			newPair.SellTrade->Stock			= *(new Symbol());
			newPair.SellTrade->Stock.Name		= m_DataModel.m_Records[nItem].SellTrade->Stock.Name;
			newPair.SellTrade->Stock.Open		= m_DataModel.m_Records[nItem].SellTrade->Stock.Open;
			newPair.SellTrade->Stock.Low		= m_DataModel.m_Records[nItem].SellTrade->Stock.Low;
			newPair.SellTrade->Stock.High		= m_DataModel.m_Records[nItem].SellTrade->Stock.High;
			newPair.SellTrade->Stock.Close		= m_DataModel.m_Records[nItem].SellTrade->Stock.Close;
			newPair.SellTrade->Stock.Bid		= m_DataModel.m_Records[nItem].SellTrade->Stock.Bid;
			newPair.SellTrade->Stock.Ask		= m_DataModel.m_Records[nItem].SellTrade->Stock.Ask;
			newPair.SellTrade->Stock.Ratio		= m_DataModel.m_Records[nItem].SellTrade->Stock.Ratio;
			
			CreateSummary(newPair.BuyTrade);
			CreateSummary(newPair.SellTrade);

			m_DataModel.m_Records.push_back(newPair);
	   }
	   FillGrid();
	}
}

void PairCalculatorMain::OnBnClickedPairSelectall()
{
	for (UINT i=0; i < m_PairDataListCtrl.GetItemCount(); i++)
	{
		m_PairDataListCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
	}
}

void PairCalculatorMain::OnBnClickedPairDeselectall()
{
	LVITEM lvi;
	ZeroMemory(&lvi, sizeof(lvi));
	lvi.mask	= LVIF_STATE;
	lvi.state	= LVIS_SELECTED;
	lvi.stateMask   = LVIS_SELECTED;
	// Index = -1 will clear all selections
	m_PairDataListCtrl.SetItemState(-1, &lvi);
}

void PairCalculatorMain::OnBnClickedPairActivate()
{
	UINT i, uSelectedCount = m_PairDataListCtrl.GetSelectedCount();
	int  nItem = -1;
	if (uSelectedCount > 0)
	{
	   for (i=0;i < uSelectedCount;i++)
	   {
		   PairTrade *newPair = NULL;
		   nItem = m_PairDataListCtrl.GetNextItem(nItem, LVNI_SELECTED);
		   newPair = &(m_DataModel.m_Records[nItem]);
		   newPair->IsActive = true;
		   newPair->Status = "Activated";

		   //delete newPair;
	   }
	   m_PairDataListCtrl.DeleteAllItems();
	   FillGrid();
	}
}

void PairCalculatorMain::SendOrders()
{
	for(size_t rowId = 0; rowId < m_DataModel.m_Records.size() ; ++rowId)
	{
		if (m_DataModel.m_Records[rowId].IsActive && m_DataModel.m_Records[rowId].Evalution)
		{
			//Buy Order
			{
				L_Summary *summary = m_DataModel.m_Records[rowId].BuyTrade->Summary;
				int Qty = m_DataModel.m_Records[rowId].BuyTrade->Qty;
				long orderType;
				double price = 0;
				if(m_DataModel.m_Records[rowId].BuyTrade->OrderPriceOn == "M")
				{
					orderType = L_OrderType::MARKET;
					price = summary->L_Bid();
				}
				else
				{
					orderType = L_OrderType::LIMIT;
					if(m_DataModel.m_Records[rowId].BuyTrade->OrderPriceOn == "B")
					{
						price = summary->L_Bid();
					}
					else if(m_DataModel.m_Records[rowId].BuyTrade->OrderPriceOn == "A")
					{
						price = summary->L_Ask();
					}
					else if(m_DataModel.m_Records[rowId].BuyTrade->OrderPriceOn == "L")
					{
						price = summary->L_LastPrice();
					}
					else if(m_DataModel.m_Records[rowId].BuyTrade->OrderPriceOn == "P")
					{
						price = (summary->L_Bid()  + summary->L_Ask())/2;
					}
				}
				CString destinationMarket = m_DataModel.m_Records[rowId].BuyTrade->OrderDestination;
				if(destinationMarket.IsEmpty())
				{
					destinationMarket = "NSDQ";
				}
				account->L_SendOrder(summary, orderType, L_Side::BUY, Qty, price - 0.01, destinationMarket, L_TIF::DAY );
				//L_AddMessageToExtensionWnd("OnBnClickedSendOrder");
			}

			//Sell Order
			{
				L_Summary *summary = m_DataModel.m_Records[rowId].SellTrade->Summary;
				int Qty = m_DataModel.m_Records[rowId].SellTrade->Qty;
				long orderType;
				double price = 0;
				if(m_DataModel.m_Records[rowId].SellTrade->OrderPriceOn == "M")
				{
					orderType = L_OrderType::MARKET;
					price = summary->L_Ask();
				}
				else
				{
					orderType = L_OrderType::LIMIT;
					if(m_DataModel.m_Records[rowId].SellTrade->OrderPriceOn == "B")
					{
						price = summary->L_Bid();
					}
					else if(m_DataModel.m_Records[rowId].SellTrade->OrderPriceOn == "A")
					{
						price = summary->L_Ask();
					}
					else if(m_DataModel.m_Records[rowId].SellTrade->OrderPriceOn == "L")
					{
						price = summary->L_LastPrice();
					}
					else if(m_DataModel.m_Records[rowId].SellTrade->OrderPriceOn == "P")
					{
						price = (summary->L_Bid()  + summary->L_Ask())/2;
					}
				}
				CString destinationMarket = m_DataModel.m_Records[rowId].SellTrade->OrderDestination;
				if(destinationMarket.IsEmpty())
				{
					destinationMarket = "NSDQ";
				}
				account->L_SendOrder(summary, orderType, L_Side::SELL, Qty, price + 0.01, destinationMarket, L_TIF::DAY );
				m_DataModel.m_Records[rowId].Status = "Sent";
				m_DataModel.m_Records[rowId].IsActive = false;
			}
		}
	}
}

void PairCalculatorMain::OnBnClickedPairDeactivate()
{
	UINT i, uSelectedCount = m_PairDataListCtrl.GetSelectedCount();
	int  nItem = -1;
	if (uSelectedCount > 0)
	{
	   for (i=0;i < uSelectedCount;i++)
	   {
		   PairTrade *newPair = NULL;
		   nItem = m_PairDataListCtrl.GetNextItem(nItem, LVNI_SELECTED);
		   newPair = &(m_DataModel.m_Records[nItem]);
		   newPair->IsActive = false;
		   newPair->Status = "Deactivated";

		   delete newPair;
	   }
	   FillGrid();
	}
}

void PairCalculatorMain::OnCustomdrawList ( NMHDR* pNMHDR, LRESULT* pResult )
{
	if(m_DataModel.m_Records.size() > 0)
	{
		NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
		*pResult = 0;
		switch(pLVCD->nmcd.dwDrawStage)
		{
			case CDDS_PREPAINT:
			{
				*pResult = CDRF_NOTIFYITEMDRAW;
				return;
			}
			case CDDS_ITEMPREPAINT:
			{
				if(m_DataModel.m_Records[pLVCD->nmcd.dwItemSpec].IsActive)
				{
					//COLORREF crText;
					//crText = RGB(255,0,0);
					//pLVCD->clrText = crText;
					/*COLORREF crBkgnd;
					crBkgnd = RGB(255,0,0);
					pLVCD->clrTextBk = crBkgnd;*/
				}
				if(m_DataModel.m_Records[pLVCD->nmcd.dwItemSpec].IsActive)
				{
					pLVCD->clrTextBk = RGB(171,219,119);//Grean
				}
				if(m_DataModel.m_Records[pLVCD->nmcd.dwItemSpec].Status == "Sent")
				{
					pLVCD->clrTextBk = RGB(178,178,178);//Gray
				}

				*pResult = CDRF_DODEFAULT;
				return;
			}
			case  CDDS_SUBITEM | CDDS_PREPAINT | CDDS_ITEM:
			{
				if(m_DataModel.m_Records[pLVCD->nmcd.dwItemSpec].IsActive)
				{
					pLVCD->clrTextBk = RGB(255,0,0);
				}
				if(m_DataModel.m_Records[pLVCD->nmcd.dwItemSpec].Status == "Sent")
				{
					pLVCD->clrTextBk = RGB(178,178,178);
				}

				*pResult = CDRF_DODEFAULT;
				return;
			}

		}
	}
}

void PairCalculatorMain::CreateSummary(Trade *trade)
{
	DeleteSummary(trade);

	trade->Summary = L_CreateSummary(trade->Stock.Name);
	trade->Summary->L_Attach(this);
}

void PairCalculatorMain::DeleteSummary(Trade *trade)
{
	if (trade->Summary)
	{
		trade->Summary->L_Detach(this);
		L_DestroySummary(trade->Summary);
	}
}

void PairCalculatorMain::OnHeaderClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
	if(bHeaderClickedStart)
	{
		bHeaderClickedStart = false;
		if(phdr->iItem == 7) //If Status is clicked
		{
			bSortStatusAscend = false;
			std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), DataSortPredicateAscending);
			
			/*if(bSortStatusAscend)
			{
				bSortStatusAscend = false;
				std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), DataSortPredicateDescending);
			}
			else
			{
				bSortStatusAscend = true;
				std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), DataSortPredicateAscending);
			}*/
			m_PairDataListCtrl.DeleteAllItems();
			FillGrid();
		}

		if(phdr->iItem == 2) //If Symbol1 is clicked
		{
			bSortSymbol1Ascend = false;
			std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), Symbol1SortPredicateAscending);
			/*if(bSortSymbol1Ascend)
			{
				bSortSymbol1Ascend = false;
				std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), Symbol1SortPredicateDescending);
			}
			else
			{
				bSortSymbol1Ascend = true;
				std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), Symbol1SortPredicateAscending);
			}*/
			m_PairDataListCtrl.DeleteAllItems();
			FillGrid();
		}
		if(phdr->iItem == 4) //If Symbol2 is clicked
		{
			bSortSymbol2Ascend = false;
			std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), Symbol2SortPredicateAscending);
			/*if(bSortSymbol2Ascend)
			{
				bSortSymbol2Ascend = false;
				std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), Symbol2SortPredicateDescending);
			}
			else
			{
				bSortSymbol2Ascend = true;
				std::sort(m_DataModel.m_Records.begin(), m_DataModel.m_Records.end(), Symbol2SortPredicateAscending);
			}*/
			m_PairDataListCtrl.DeleteAllItems();
			FillGrid();
		}
		bHeaderClickedStart = true;
	}
	// TODO: Add your control notification handler code here
	*pResult = 0;
}

bool PairCalculatorMain::DataSortPredicateAscending(const PairTrade &d1, const PairTrade &d2)
{
	return d1.Status < d2.Status;
}

bool PairCalculatorMain::DataSortPredicateDescending(const PairTrade &d1, const PairTrade &d2)
{
	bool retvalue = !(d1.Status < d2.Status);
	return retvalue;
}

bool PairCalculatorMain::Symbol1SortPredicateAscending(const PairTrade &d1, const PairTrade &d2)
{
	if(d1.Nature == 'B')
	{  
		return d1.BuyTrade->Stock.Name < d2.BuyTrade->Stock.Name;
	}
	else
	{
		return d1.SellTrade->Stock.Name < d2.SellTrade->Stock.Name;
	}
}
bool PairCalculatorMain::Symbol1SortPredicateDescending(const PairTrade &d1, const PairTrade &d2)
{
	bool retvalue = false;
	if(d1.Nature == 'B')
	{  
		retvalue = d1.BuyTrade->Stock.Name >= d2.BuyTrade->Stock.Name;
	}
	else
	{
		retvalue = d1.SellTrade->Stock.Name >= d2.SellTrade->Stock.Name;
	}
	return retvalue;
}

bool PairCalculatorMain::Symbol2SortPredicateAscending(const PairTrade &d1, const PairTrade &d2)
{
	if(d1.Nature == 'B')
	{  
		return d1.SellTrade->Stock.Name < d2.SellTrade->Stock.Name;
	}
	else
	{
		return d1.BuyTrade->Stock.Name < d2.BuyTrade->Stock.Name;
	}
}
bool PairCalculatorMain::Symbol2SortPredicateDescending(const PairTrade &d1, const PairTrade &d2)
{
	bool retvalue = false;
	if(d1.Nature == 'B')
	{  
		retvalue = d1.SellTrade->Stock.Name >= d2.SellTrade->Stock.Name;
	}
	else
	{
		retvalue = d1.BuyTrade->Stock.Name >= d2.BuyTrade->Stock.Name;
	}
	return retvalue; 
}





